/*
 * Handles incoming file requests from peers
 */
package rapidp2p.backend;

/**
 *
 * @author Rudy
 */

import java.io.*;
import java.net.*;
import java.util.UUID;
import java.util.*;
import java.util.logging.Level;
import java.util.logging.Logger;

public class RequestHandler {

    // Implemented HTTP status phrases
    private final String STATUS_OK = "200 OK",
            STATUS_BADREQUEST = "400 Bad_Request",
            STATUS_FORBIDDEN = "403 Forbidden",
            STATUS_NOTFOUND = "404 Not_Found",
            STATUS_SERVERERROR = "500 Internal_Server_Error",
            STATUS_NOTIMPLEMENTED = "501 Not_Implemented",
            STATUS_NOTSUPPORTED = "505 HTTP_Version_Not_Supported";
    // server receiving request
    //  private P2PServer server;
    public static final int TCP_LISTEN_PORT = 6789;
    // requesting client
    private Socket client;
    // HTTP version
    private final String HTTP_VERSION = "HTTP/1.1";
    // Response headers
    Map<String, String> headers = new HashMap<String, String>();
    boolean headerSent = false;
    DataOutputStream outToClient;

    public RequestHandler() { // PROBABLY DOESNT NEED ANYTHING PASSED IN

        //this.server=svr;
        //  this.client = c;

        //default response headers if we decide to send them
        headers.put("Server", "Version_1.0");
        headers.put("Connection", "close");
        headers.put("Content-Type", "text/html");


    }

    private void sendHTTPbody(String message) {
        if (headerSent) {
            String body = message + "\r\n";
            try {

                outToClient.writeBytes(body);
            } catch (IOException ex) {
                ex.printStackTrace();
            }
        }
    }

    private void sendHTTPheader(String status) {

        if (!headerSent) {
            // prepare HTTP response
            String data = HTTP_VERSION + " " + status + "\r\n";

            System.out.println(" Request Handler sending response" + status);

            // add Headers

            try {
                //send headers
                outToClient.writeBytes(data);

            } catch (IOException ex) {
                ex.printStackTrace();
            }
            headerSent = true;
        }
    }

    public void processRequest() {
        // init request buffer
        try {
            /* Create a 'door' that listens on a TCP port */
            ServerSocket welcomeSocket = new ServerSocket(TCP_LISTEN_PORT);

            // while(true){ //needed?
            //accept client connection
            Socket connectionSocket = welcomeSocket.accept();
            BufferedReader in = new BufferedReader(new InputStreamReader(connectionSocket.getInputStream()));
            outToClient = new DataOutputStream(connectionSocket.getOutputStream());


            String clientHeaders = in.readLine();

            String[] status = clientHeaders.split(" ", 3);
            String req = status[0];
            String fileName = status[1];
            String version = status[2];

            fileName = fileName.replace('/', File.separatorChar);
            fileName = fileName.replace('\\', File.separatorChar); // format filename

            File dlFile = new File(fileName);
            System.out.println(fileName + " is the file to be transfered");

            if (!req.startsWith("GET")) { // not a get request

                sendHTTPheader(STATUS_NOTIMPLEMENTED); // only GET implemented

            } else if (!version.startsWith("HTTP/1.1")) {   // wrong version

                sendHTTPheader(STATUS_NOTSUPPORTED);
            } else if (!dlFile.exists()) {  // file not found

                sendHTTPheader(STATUS_NOTFOUND);
            } else { // send transfer info

                sendHTTPheader(STATUS_OK);

                int portNO = 4000; //random
                Long size = dlFile.length();
                String sizest = size.toString();
                byte songBytes[] = new byte[Integer.parseInt(sizest)];

                String msg = "PORT:" + portNO + ":SIZE:" + size;
                sendHTTPbody(msg);
                //response sent

                // send file
                System.out.println("sending file");

                FileInputStream sendingFile = null;
                try {
                    sendingFile = new FileInputStream(dlFile);
                } catch (FileNotFoundException ex) {
                    Logger.getLogger(RequestHandler.class.getName()).log(Level.SEVERE, null, ex);
                }

                BufferedInputStream bis = new BufferedInputStream(sendingFile);
                System.out.println("got to BuffStream");
                try {
                    bis.read(songBytes, 0, songBytes.length);
                    System.out.println("got to stream read");
                    outToClient.write(songBytes, 0, songBytes.length);
                    outToClient.flush();
                    outToClient.close();
                    connectionSocket.close();
                    System.out.println("\nFile  sent.");
                    // File sent, exit the main method
                    return;
                } catch (IOException ex) {
                    // Do exception handling
                }
            }

        }
        catch (IOException ex) {
            Logger.getLogger(RequestHandler.class.getName()).log(Level.SEVERE, null, ex);
        }        // TODO logic for transfer

         }
        public static void main(String[]args){
		RequestHandler rh = new RequestHandler();
		rh.processRequest();
	}






    
}
